﻿// CRecipe.cpp: 实现文件
//

#include "pch.h"
#include <string>

#include "Cobot_PrintServer.h"
#include "CRecipe.h"
#include "JsonServer.h"
#include "PrinterImpl.h"

#include "afxdialogex.h"


// CRecipe 对话框

IMPLEMENT_DYNAMIC(CRecipe, CDialog)

CRecipe::CRecipe(CWnd* pParent /*=nullptr*/)
	: CDialog(IDD_DLG_REPICE, pParent)
	, m_strName(_T(""))
	, m_strSex(_T(""))
	, m_strAge(_T(""))
	, m_strRecipeID(_T(""))
{

}

CRecipe::~CRecipe()
{
}

void CRecipe::DoDataExchange(CDataExchange* pDX)
{
	CDialog::DoDataExchange(pDX);
	DDX_Control(pDX, IDC_TREE_RECIPE, m_CtrlTreeRecipe);
	DDX_Control(pDX, IDC_RECIPE_DES_LIST, m_CtrlRecipeInfo);

	DDX_Text(pDX, IDC_STATIC_NAME, m_strName);
	DDX_Text(pDX, IDC_STATIC_SEX, m_strSex);
	DDX_Text(pDX, IDC_STATIC_AGE, m_strAge);
	DDX_Text(pDX, IDC_EDIT_SERACH_RECIPEID, m_strRecipeID);
	DDX_Control(pDX, IDC_EDIT_SERACH_RECIPEID, m_CtrlSearch);
}


BEGIN_MESSAGE_MAP(CRecipe, CDialog)
	//ON_NOTIFY(NM_DBLCLK, IDC_TREE_RECIPE, &CRecipe::OnNMDblclkTreeRecipe)
	ON_MESSAGE(WM_UPDATE_WINDOW_RECIPE, OnUpdateRecipeTreeNode) // 
	ON_BN_CLICKED(IDC_BTN_PRINT, &CRecipe::OnBnClickedBtnPrint)
	ON_MESSAGE(WM_UPDATE_HISTORY_RECIPE, OnUpdateRecipeTree)  //
	ON_MESSAGE(WM_RESET_RECIPE_WINDOW, OnResetRecipeWindow)
	ON_BN_CLICKED(IDC_BTN_SEARCH, &CRecipe::OnBnClickedBtnSearch)
ON_NOTIFY(TVN_SELCHANGED, IDC_TREE_RECIPE, &CRecipe::OnTvnSelchangedTreeRecipe)
ON_EN_SETFOCUS(IDC_EDIT_SERACH_RECIPEID, &CRecipe::OnEnSetfocusEditSerachRecipeid)
//ON_WM_KEYDOWN()
//ON_EN_KILLFOCUS(IDC_EDIT_SERACH_RECIPEID, &CRecipe::OnEnKillfocusEditSerachRecipeid)
ON_WM_SIZE()
END_MESSAGE_MAP()


// CRecipe 消息处理程序


void CRecipe::init()
{
	//初始化界面;
	// item 药品名称 规格 数量 用法  货号位   机器发 人工补 
	// 设置行高的巧用方法;
	CImageList m_I;
	m_I.Create(1, 25, TRUE | ILC_COLOR32, 1, 0);
	m_CtrlRecipeInfo.SetImageList(&m_I, LVSIL_SMALL);


	DWORD dwStyle = m_CtrlRecipeInfo.GetExtendedStyle();
	dwStyle |= LVS_EX_FULLROWSELECT;// 选中某行使整行高亮（只适用与report 风格的listctrl ）
	dwStyle |= LVS_EX_GRIDLINES;// 网格线（只适用与report 风格的listctrl ）
	//dwStyle |= LVS_EX_CHECKBOXES;//item 前生成checkbox 控件

	m_CtrlRecipeInfo.SetExtendedStyle(dwStyle);

	m_CtrlRecipeInfo.InsertColumn(0, "药品名称", LVCFMT_LEFT, 130);
	m_CtrlRecipeInfo.InsertColumn(1, "规格", LVCFMT_LEFT, 125);
	m_CtrlRecipeInfo.InsertColumn(2, "数量", LVCFMT_LEFT, 70);
	m_CtrlRecipeInfo.InsertColumn(3, "用法", LVCFMT_LEFT, 130);
	//m_CtrlRecipeInfo.InsertColumn(4, "货号位", LVCFMT_LEFT, 80);
	m_CtrlRecipeInfo.InsertColumn(4, "机器发", LVCFMT_LEFT, 85);
	m_CtrlRecipeInfo.InsertColumn(5, "人工补", LVCFMT_LEFT, 85);

	// 创建根节点;
	m_RootFinish = m_CtrlTreeRecipe.InsertItem("已处理",TVI_ROOT);
	
	//m_RootPrepare = m_CtrlTreeRecipe.InsertItem("预配处方单信息",TVI_ROOT);    // 预配处方信息 未配药;
	//m_RootDir = m_CtrlTreeRecipe.InsertItem("直发处方单信息", TVI_ROOT);       // 直发处方信息 未配药;                                                              // 直发处方信息 未配药;
	
	m_CtrlTreeRecipe.Expand(m_RootFinish, TVE_EXPAND);
}

void CRecipe::addRecipeInfoNode(std::string patientId, std::string uniqueId)
{	
	// 1.首先遍历树，看当前处方信息属于哪个树节点;
	HTREEITEM hCurItem = m_CtrlTreeRecipe.GetChildItem(m_RootFinish);
	if (hCurItem == NULL)
	{	
		std::string patientString = "病人ID_" + patientId;
		HTREEITEM patientNode = m_CtrlTreeRecipe.InsertItem(patientString.c_str(), m_RootFinish);

		std::string temp;
		temp = "配药单_" + uniqueId;
		m_CtrlTreeRecipe.InsertItem(temp.c_str(), patientNode);
	}
	else
	{	
		while (hCurItem)
		{
			CString text = m_CtrlTreeRecipe.GetItemText(hCurItem);
			std::string temp = text.GetString();
			std::string selectPatientId = temp.substr(7); //截取 "病人_" 后面的病人ID信息;
			if (selectPatientId == patientId)
			{
				std::string temp;
				temp = "配药单_" + uniqueId;
				m_CtrlTreeRecipe.InsertItem(temp.c_str(), hCurItem);
				return;
			}
			hCurItem = m_CtrlTreeRecipe.GetNextSiblingItem(hCurItem);
		}

		std::string patientString = "病人ID_" + patientId;
		HTREEITEM patientNode = m_CtrlTreeRecipe.InsertItem(patientString.c_str(), m_RootFinish);

		std::string temp;
		temp = "配药单_" + uniqueId;
		m_CtrlTreeRecipe.InsertItem(temp.c_str(), patientNode);
	}
	
}

void CRecipe::showRecipeInfoInList(std::string recipeInfo)
{	
	RecipeDrugInfoSet recipeInfoset;
	JsonServer::getInstance()->parseRecipeInfo(recipeInfo, recipeInfoset);
	
	m_strName = recipeInfoset.patientName.c_str();
	m_strSex = recipeInfoset.patientSex.c_str();
	m_strAge = recipeInfoset.patientAge.c_str();

	for (const RecipeDrugInfo& info : recipeInfoset.dataSet)
	{
		int row = m_CtrlRecipeInfo.GetItemCount();
		CString index;
		index.Format("%d", row);

		m_CtrlRecipeInfo.InsertItem(row, info.name.c_str());               // 药品名称;
		m_CtrlRecipeInfo.SetItemText(row, 1, info.specification.c_str());  // 药品规格;        
		m_CtrlRecipeInfo.SetItemText(row, 2, info.num.c_str());            // 药品数量;
		m_CtrlRecipeInfo.SetItemText(row, 3, info.instruction.c_str());    // 用法;
		//m_CtrlRecipeInfo.SetItemText(row, 4, info.location.c_str());       // 货号位;
		m_CtrlRecipeInfo.SetItemText(row, 4, info.machineSendNum.c_str()); // 机器发;
		m_CtrlRecipeInfo.SetItemText(row, 5, info.manualSuppleNum.c_str());// 人工补;

	}

	UpdateData(false);
}

void CRecipe::ChangeSize(UINT nID, int x, int y)
{
	CWnd* pWnd;
	pWnd = GetDlgItem(nID);
	if (pWnd != NULL) //判断是否为空，因为在窗口创建的时候也会调用OnSize函数，但是此时各个控件还没有创建，Pwnd为空
	{
		CRect rec;
		pWnd->GetWindowRect(&rec); //获取控件变化前的大小
		ScreenToClient(&rec); //将控件大小装换位在对话框中的区域坐标
		rec.left = rec.left * x / m_rect.Width(); //按照比例调整空间的新位置
		rec.top = rec.top * y / m_rect.Height();
		rec.bottom = rec.bottom * y / m_rect.Height();
		rec.right = rec.right * x / m_rect.Width();
		pWnd->MoveWindow(rec); //伸缩控件
	}
}

BOOL CRecipe::OnInitDialog()
{
	CDialog::OnInitDialog();

	// TODO:  在此添加额外的初始化
	init();
	return TRUE;  // return TRUE unless you set the focus to a control
				  // 异常: OCX 属性页应返回 FALSE
}


void CRecipe::OnNMDblclkTreeRecipe(NMHDR* pNMHDR, LRESULT* pResult)
{	
	// TODO: 在此添加控件通知处理程序代码
	//HTREEITEM hCurTree = m_CtrlTreeRecipe.GetSelectedItem();
	//if (m_CtrlTreeRecipe.GetParentItem(hCurTree) != NULL)
	//{	
	//	// 清空表;
	//	m_CtrlRecipeInfo.DeleteAllItems();

	//	CString text = m_CtrlTreeRecipe.GetItemText(hCurTree);
	//	std::string temp = CT2A(text.GetString());

	//	// 解析字符串;
	//	std::string recipeId = temp.substr(5); //截取 "处方_" 后面的处方ID信息;

	//	std::string recipeInfo = JsonServer::getInstance()->getRecipeString(recipeId);
	//		
	//	if (!recipeInfo.empty())
	//	{
	//		showRecipeInfoInList(recipeInfo);
	//	}
	//	// 子节点;
	//	/*char* pData  = (char*)m_CtrlTreeRecipe.GetItemData(hCurTree);
	//	std::string test;
	//	strcpy((char*)test.c_str(),pData);
	//	int i = 0;*/
	//}
	
	*pResult = 0;
}

LRESULT CRecipe::OnUpdateRecipeTreeNode(WPARAM wParam, LPARAM lParam)
{	
	std::string uniqueId = JsonServer::getInstance()->getUniqueID();
	std::string patientId = JsonServer::getInstance()->getPatientID();

	addRecipeInfoNode(patientId,uniqueId);
	return true;
}

LRESULT CRecipe::OnUpdateRecipeTree(WPARAM wParam, LPARAM lParam)
{	
	std::map<std::string, std::vector<std::string>> patientList = JsonServer::getInstance()->getPatientList();
	if (patientList.empty())
	{
		return false;
	}

	for (auto it = patientList.begin();it != patientList.end(); it++)
	{	
		for (auto itVec = it->second.begin(); itVec != it->second.end(); itVec++)
		{	
			// todo: 可以优化; 可以一次添加所有节点,而不是一个个添加;
			addRecipeInfoNode(it->first, *itVec);
		}
	}
	
	return true;
}

LRESULT CRecipe::OnResetRecipeWindow(WPARAM wParam, LPARAM lParam)
{	
	if (!m_CtrlTreeRecipe.ItemHasChildren(m_RootFinish))
	{
		return false;
	}

	HTREEITEM hTreeSubItem = m_CtrlTreeRecipe.GetChildItem(m_RootFinish);
	do
	{	
		HTREEITEM hTempItem = hTreeSubItem;
		hTreeSubItem = m_CtrlTreeRecipe.GetNextSiblingItem(hTreeSubItem); // 获取当前节点的兄弟节点;
		m_CtrlTreeRecipe.DeleteItem(hTempItem);
		
	} while (hTreeSubItem != NULL);

	m_CtrlRecipeInfo.DeleteAllItems();

	return true;
}

void CRecipe::OnBnClickedBtnPrint()
{
	// TODO: 在此添加控件通知处理程序代码
	// 补打功能，历史打印记录重新打印;
	if (PrinterImpl::getInstance()->getPrintStatus())
	{
		MessageBox("打印机异常,请重启服务器!");
		return;
	}

	// 获取控件选中的item;
	HTREEITEM item = m_CtrlTreeRecipe.GetSelectedItem();
	if (m_CtrlTreeRecipe.GetParentItem(item) != NULL && m_CtrlTreeRecipe.GetChildItem(item) == NULL)
	{	
		// 获取当前节点的父节点;
		HTREEITEM parentItem = m_CtrlTreeRecipe.GetParentItem(item);
		CString patientString = m_CtrlTreeRecipe.GetItemText(parentItem);
		std::string tempString = patientString.GetString();
		std::string patientId = tempString.substr(7); // //截取 "病人ID_" 后面的病人ID信息;

		// 解析字符串;
		CString text = m_CtrlTreeRecipe.GetItemText(item);
		std::string temp = CT2A(text.GetString());
		std::string uniqueId = temp.substr(7); //截取 "配药单_" 后面的uniqueId;
		std::string recipeInfo = JsonServer::getInstance()->getPrintString(patientId, uniqueId);

		if (!recipeInfo.empty())
		{	
			PrinterImpl::getInstance()->print(recipeInfo);
		}
		else
		{
			MessageBox("打印数据空!");
		}	
	}
	else 
	{	
		MessageBox("未选中节点!");
	}
}


void CRecipe::OnBnClickedBtnSearch()
{
	// TODO: 在此添加控件通知处理程序代码
	UpdateData(true);
	std::string searchPatientId = m_strRecipeID.GetString();
	if (searchPatientId.empty())
	{
		MessageBox("请输入病人ID!");
		return;
	}

	if (m_CtrlTreeRecipe.ItemHasChildren(m_RootFinish))
	{	
		HTREEITEM hChild = m_CtrlTreeRecipe.GetChildItem(m_RootFinish);
		do
		{	
			CString text = m_CtrlTreeRecipe.GetItemText(hChild);
			std::string temp = text.GetString();
			std::string patientId = temp.substr(7); //截取 "病人_" 后面的病人ID信息;

			if (searchPatientId == patientId)
			{	
				m_CtrlTreeRecipe.SetFocus();
				m_CtrlRecipeInfo.DeleteAllItems();

				
				HTREEITEM hTreeSubItem = m_CtrlTreeRecipe.GetChildItem(hChild);
				m_CtrlTreeRecipe.SelectItem(hTreeSubItem);

				//CString text = m_CtrlTreeRecipe.GetItemText(hTreeSubItem);
				//std::string temp = text.GetString();
				//std::string uniqueId = temp.substr(7); //截取 "配药单_" 后面的uniqueId;
				//
				//std::string recipeInfo = JsonServer::getInstance()->getRecipeString(patientId, uniqueId);
				//if (!recipeInfo.empty())
				//{
				//	showRecipeInfoInList(recipeInfo);
				//}

				return;
			}

			hChild = m_CtrlTreeRecipe.GetNextSiblingItem(hChild); // 获取当前节点的兄弟节点;
		} while (hChild != NULL);
	}

	//if (m_CtrlTreeRecipe.ItemHasChildren(m_RootPrepare))
	//{
	//	HTREEITEM hChild = m_CtrlTreeRecipe.GetChildItem(m_RootFinish);
	//	do
	//	{
	//		CString text = m_CtrlTreeRecipe.GetItemText(hChild);
	//		std::string temp = text.GetString();
	//		std::string recipeId = temp.substr(5); //截取 "处方_" 后面的处方ID信息;

	//		if (searchRecipeId == recipeId)
	//		{
	//			m_CtrlTreeRecipe.SetFocus();
	//			m_CtrlTreeRecipe.SelectItem(hChild);
	//			m_CtrlRecipeInfo.DeleteAllItems();

	//			std::string recipeInfo = JsonServer::getInstance()->getRecipeString(searchRecipeId);
	//			if (!recipeInfo.empty())
	//			{
	//				showRecipeInfoInList(recipeInfo);
	//			}
	//			return;
	//		}

	//		hChild = m_CtrlTreeRecipe.GetNextSiblingItem(hChild); // 获取当前节点的兄弟节点;
	//	} while (hChild != NULL);
	//}

	//if (m_CtrlTreeRecipe.ItemHasChildren(m_RootDir))
	//{
	//	HTREEITEM hChild = m_CtrlTreeRecipe.GetChildItem(m_RootFinish);
	//	do
	//	{
	//		CString text = m_CtrlTreeRecipe.GetItemText(hChild);
	//		std::string temp = text.GetString();
	//		std::string recipeId = temp.substr(5); //截取 "处方_" 后面的处方ID信息;

	//		if (searchRecipeId == recipeId)
	//		{
	//			m_CtrlTreeRecipe.SetFocus();
	//			m_CtrlTreeRecipe.SelectItem(hChild);
	//			m_CtrlRecipeInfo.DeleteAllItems();

	//			std::string recipeInfo = JsonServer::getInstance()->getRecipeString(searchRecipeId);
	//			if (!recipeInfo.empty())
	//			{
	//				showRecipeInfoInList(recipeInfo);
	//			}
	//			return;
	//		}

	//		hChild = m_CtrlTreeRecipe.GetNextSiblingItem(hChild); // 获取当前节点的兄弟节点;
	//	} while (hChild != NULL);
	//}
	
	MessageBox("未查询到数据!");
}

void CRecipe::OnTvnSelchangedTreeRecipe(NMHDR* pNMHDR, LRESULT* pResult)
{
	LPNMTREEVIEW pNMTreeView = reinterpret_cast<LPNMTREEVIEW>(pNMHDR);
	// TODO: 在此添加控件通知处理程序代码

	HTREEITEM hItem = pNMTreeView->itemNew.hItem;

	if (m_CtrlTreeRecipe.GetParentItem(hItem) != NULL && m_CtrlTreeRecipe.GetChildItem(hItem) == NULL)
	{	
		// 清空表;
		m_CtrlRecipeInfo.DeleteAllItems();

		// 获取当前节点的父节点;
		HTREEITEM parentItem = m_CtrlTreeRecipe.GetParentItem(hItem);
		CString patientString = m_CtrlTreeRecipe.GetItemText(parentItem);
		std::string tempString = patientString.GetString();
		std::string patientId = tempString.substr(7); // //截取 "病人ID_" 后面的病人ID信息;

		CString text = m_CtrlTreeRecipe.GetItemText(hItem);
		std::string temp = text.GetString();
		std::string uniqueId = temp.substr(7); //截取 "配药单_" 后面的处方ID信息;
		std::string recipeInfo = JsonServer::getInstance()->getRecipeString(patientId, uniqueId);

		if (!recipeInfo.empty())
		{
			showRecipeInfoInList(recipeInfo);
		}
	}

	*pResult = 0;
}


void CRecipe::OnEnSetfocusEditSerachRecipeid()
{
	// TODO: 在此添加控件通知处理程序代码
	//int ret = WinExec("osk.exe",SW_SHOWNORMAL);
	ShellExecute(NULL, "open", "osk.exe", NULL, NULL, SW_SHOWNORMAL);
}


BOOL CRecipe::PreTranslateMessage(MSG* pMsg)
{
	// TODO: 在此添加专用代码和/或调用基类
	if (pMsg->message == WM_KEYDOWN)
	{
		switch (pMsg->wParam)
		{
			case VK_ESCAPE:
				return TRUE;
			case VK_RETURN:
			{	
				GetDlgItem(IDC_BTN_SEARCH)->SetFocus();
				// 结束后删除虚拟键盘;
				if (HWND hwnd = ::FindWindow("OSKMainClass", 0))
				{
					::SendMessage(hwnd, WM_DESTROY, 0, 0); // WM_DESTROY WM_CLOSE
				} 
				return TRUE;
			}
		}
	}

	return CDialog::PreTranslateMessage(pMsg);
}

void CRecipe::OnSize(UINT nType, int cx, int cy)
{
	CDialog::OnSize(nType, cx, cy);

	// TODO: 在此处添加消息处理程序代码
	if (nType != SIZE_MINIMIZED) //判断窗口是不是最小化了，因为窗口最小化之后 ，窗口的长和宽会变成0，当前一次变化的时就会出现除以0的错误操作
	{
		// IDC_STATIC;
		ChangeSize(IDC_GROUP_LIST, cx, cy); //对每一个控件依次做调整

		ChangeSize(IDC_PATIENT_ID, cx, cy);
		ChangeSize(IDC_EDIT_SERACH_RECIPEID, cx, cy);
		ChangeSize(IDC_BTN_SEARCH, cx, cy);

		ChangeSize(IDC_TREE_RECIPE, cx, cy);

		ChangeSize(IDC_GROUP_GENERA, cx, cy);
		ChangeSize(IDC_STATIC_NAME_TEXT, cx, cy);
		ChangeSize(IDC_STATIC_SEX_TEXT, cx, cy);
		ChangeSize(IDC_STATIC_AGE_TEXT, cx, cy);

		ChangeSize(IDC_STATIC_AGE, cx, cy);
		ChangeSize(IDC_STATIC_SEX, cx, cy);
		ChangeSize(IDC_STATIC_NAME, cx, cy);

		ChangeSize(IDC_RECIPE_DES_LIST, cx, cy);
		ChangeSize(IDC_BTN_PRINT, cx, cy);
		

		GetClientRect(&m_rect); //最后要更新对话框的大小，当做下一次变化的旧坐标
	}
}
